﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using SpriteGame.UI;
using SpriteGame.Helpers;
using Microsoft.Xna.Framework.Input;
using FarseerPhysics.Dynamics;
using SpriteGame.Entities;
using SpriteGame.Rendering;

namespace SpriteGame.Rendering
{
    public class Particles
    {
        Scene parent;

        public Particles(Scene _parent)
        {
            parent = _parent;
            LoadParticles();
        }

        List<Particle> activeParticles;
        Stack<Particle> inActiveparticles;

        float[] randoms = new float[400];

        public void LoadParticles()
        {
            activeParticles = new List<Particle>();
            inActiveparticles = new Stack<Particle>();

            for (int i = 0; i < 100; i++)
            {
                randoms[i] = Rand.RandomFloat();
            }

            for (int i = 0; i < 10000; i++)
            {
                Particle p = new Particle();
                p.Finished += new Particle.ClickHandler(p_Finished);
                inActiveparticles.Push(p);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_pos"></param>
        /// <param name="_amount">The number of particles, max of 100!</param>
        public void CreateExplosion(Vector2 _pos, int _amount)
        {
            for (int i = 0; i < _amount; i++)
            {
                AddParticle(_pos, new Vector2(randoms[i], randoms[i + 1]), true);
            }
        }

        void p_Finished(Particle _owner)
        {
            activeParticles.Remove(_owner);
            inActiveparticles.Push(_owner);
        }

        public void AddParticle(Vector2 _position, Vector2 _velocity)
        {
            if (inActiveparticles.Count < 0)
                return;

            Particle p = inActiveparticles.Pop();
            p.Enable(_position, _velocity, "Textures/Particles/WhiteDot");
            activeParticles.Add(p);
        }

        public void AddParticle(Vector2 _position, Vector2 _velocity, bool _gravity)
        {
            if (inActiveparticles.Count < 0)
                return;

            Particle p = inActiveparticles.Pop();
            p.Enable(_position, _velocity, "Textures/Particles/WhiteDot", true);
            activeParticles.Add(p);
        }

        public void Update(GameTime _time)
        {
            for (int i = 0; i < activeParticles.Count; i++)
            {
                activeParticles[i].Update();
            }
        }

        public void Draw(ShapeRenderer _batch)
        {
            for (int i = 0; i < activeParticles.Count; i++)
            {
                activeParticles[i].Draw(_batch);
            }
        }
    }

    public class Particle
    {
        float widthHeight;
        Vector2 position;
        Vector2 velocity;
        Vector2 velocityMultiplier;
        String texture;

        int lifeTime = 0;

        public event ClickHandler Finished;
        public delegate void ClickHandler(Particle _owner);

        public Particle()
        {
            position = Vector2.Zero;
            velocity = Vector2.Zero;
            texture = "";
            widthHeight = 1.6f;
        }

        void Disable()
        {
            position = Vector2.Zero;
            velocity = Vector2.Zero;
            texture = "";
            lifeTime = 0;
            widthHeight = 1.6f;
        }

        public void Enable(Vector2 _pos, Vector2 _vel, string _tex)
        {
            position = _pos;
            velocity = _vel;
            texture = _tex;
            velocityMultiplier = Vector2.Zero;
        }

        public void Enable(Vector2 _pos, Vector2 _vel, string _tex, bool _gravity)
        {
            position = _pos;
            velocity = _vel;
            texture = _tex;
            velocityMultiplier = new Vector2(0, -0.05f);
        }

        public void Update()
        {
            velocity += velocityMultiplier;
            position += velocity;
            lifeTime++;

            if (widthHeight > .01)
            {
                widthHeight -= 0.05f;
            }

            if (lifeTime > 190)
            {
                Disable();
                if (Finished != null)
                {
                    Finished.Invoke(this);
                }
            }
        }

        public void Draw(ShapeRenderer _batch)
        {
            _batch.DrawQuad(position, 0.0f, widthHeight, widthHeight, TextureLibrary.GetTexture(texture));
        }
    }
}
